#include "graphics.h"
#include "SDL2/SDL_image.h"

void Graphics::init(int window_w, int window_h)
{
	window = SDL_CreateWindow(
		WINDOW_TITLE,
		/* initial position of window */
		SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
		/* initial dimensions of window */
		window_w, window_h,
		/* show immediately | highdpi | resizability */
		SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE
	);
	if (window == nullptr) {
		SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "SDL_CreateWindow error: %s\n", SDL_GetError());
		exit(EXIT_FAILURE);
	}

	renderer = SDL_CreateRenderer(
		/* window for renderer, index of rendering driver (-1 means automatic) */
		window, -1,
		/* use hardware acceleration | vsync | support rendering to texture */
		SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE
	);
	if (renderer == nullptr) {
		SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "SDL_CreateRenderer error: %s\n", SDL_GetError());
		exit(EXIT_FAILURE);
	}

	/* initial texture for renderer context */
	display = SDL_CreateTexture(
		renderer,
		/* pixel bit format, render targetability */
		SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
		window_w, window_h
	);
	if (display == nullptr) {
		SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "SDL_CreateTexture error: %s\n", SDL_GetError());
		exit(EXIT_FAILURE);
	}

	if (TTF_Init() < 0) {
		SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "TTF_Init error: %s\n", TTF_GetError());
		exit(EXIT_FAILURE);
	}

	font_big    = TTF_OpenFont("font/UtmThuphapThienAn-VnBz.ttf", 128);
	font_medium = TTF_OpenFont("font/UtmThuphapThienAn-VnBz.ttf", 64);
	font_small  = TTF_OpenFont("font/UtmThuphapThienAn-VnBz.ttf", 40);
	if (font_big == nullptr || font_medium == nullptr || font_small == nullptr) {
		SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "TTF_OpenFont error: %s\n", TTF_GetError());
		exit(EXIT_FAILURE);
	}

	/* initialize SDL image */
	int imgFlags = IMG_INIT_PNG;
	if(!(IMG_Init(imgFlags) & imgFlags)) {
		SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "SDL_image error: %s\n", IMG_GetError());
		exit(EXIT_FAILURE);
	}

	SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
	SDL_SetRenderTarget(renderer, display);
	SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
}

void Graphics::cleanup()
{
	SDL_DestroyTexture(display);
	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(window);
}

void Graphics::render(State& state, stack<shared_ptr<Scene>>& active_scenes)
{
	/* clear screen */
	SDL_RenderClear(renderer);

	/* do the important stuff */
	SDL_SetRenderTarget(renderer, nullptr);
	SDL_RenderCopy(renderer, display, nullptr, nullptr);

	/* render active scene */
	active_scenes.top()->render(renderer);

	SDL_RenderPresent(renderer);
}

SDL_Texture *Graphics::load_png_to_texture(string path)
{
	SDL_Texture *png_texture = nullptr;
	SDL_Surface *png_surface = IMG_Load(path.c_str());
	if (png_surface == nullptr) {
		SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "SDL_image error: unable to load image %s: %s\n", path.c_str(), IMG_GetError());
	} else {
		png_texture = SDL_CreateTextureFromSurface(renderer, png_surface);
		if (png_texture == nullptr)
			SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "error: unable to create texture for image %s: %s\n", path.c_str(), SDL_GetError());

		SDL_FreeSurface(png_surface);
	}

	return png_texture;
}

SDL_Texture *Graphics::load_text_to_texture(string text, SDL_Color color, FontSelector sel)
{
	TTF_Font *font = sel == FONT_BIG ? font_big : (sel == FONT_MEDIUM ? font_medium : font_small);
	SDL_Texture *text_texture = nullptr;
	SDL_Surface *text_surface = TTF_RenderText_Blended(font, text.c_str(), color);
	if (text_surface == nullptr) {
		SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "SDL_ttf error: unable to load text \"%s\": %s\n", text.c_str(), TTF_GetError());
	} else {
		text_texture = SDL_CreateTextureFromSurface(renderer, text_surface);
		if (text_texture == nullptr)
			SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "error: unable to create texture for text \"%s\": %s\n", text.c_str(), SDL_GetError());

		SDL_FreeSurface(text_surface);
	}

	return text_texture;
}